package com.base.thread.demo_14;

/**
 * 序列生成器
 * @ClassName: Sequence
 * @Description: 
 * @Author xuyou
 * @DateTime 2019年12月7日 下午4:07:03
 */
public class Sequence {
	
	//private static int value;
	private int value;
	
	/**
	 * synchronized 放在普通方法上，内置锁就是当前类的实例 不用synchronized会出现线程安全性问题
	 * @return
	 */
//	public synchronized int getNext() {
//		return value ++;
//	}
	public  int getNext() {
		return value ++;
	}
	
	/**
	 * 修饰静态方法，内置锁是当前的Class字节码对象
	 * Sequence.class
	 * @return
	 */
	public static synchronized int getPrevious() {
//		return value --;
		return 0;
	}
	
	public int xx () {
		// 字节码指令  刚进入代码块的时候指令是monitorenter
		synchronized (Sequence.class) {
			if(value > 0) {
				return value;
			} else {
				return -1;
			}
			
		}
		// 代码块执行完毕以后的指令是monitorexit
		
//		在cmd中使用 javap -verbose Sequence.class 可以查看字节码指令
//        4: monitorenter
//        5: aload_0
//        6: getfield      #18   // Field value:I
//        9: ifle          19
//       12: aload_0
//       13: getfield      #18  // Field value:I
//       16: aload_1
//       17: monitorexit
		
		
	}
	
	public static void main(String[] args) {
		
		Sequence s = new Sequence();
//		while(true) {
//			System.out.println(s.getNext());
//		}
		
		new Thread(new Runnable() {
			
			@Override
			public void run() {
				while(true) {
					System.out.println(Thread.currentThread().getName() + " " + s.getNext());
					try {
						Thread.sleep(100);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		}).start();
		
		new Thread(new Runnable() {
			
			@Override
			public void run() {
				while(true) {
					System.out.println(Thread.currentThread().getName() + " " + s.getNext());
					try {
						Thread.sleep(100);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		}).start();
		
		new Thread(new Runnable() {
			
			@Override
			public void run() {
				while(true) {
					System.out.println(Thread.currentThread().getName() + " " + s.getNext());
					try {
						Thread.sleep(100);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		}).start();
		
	}

}
